home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / recovinfo / recovinfo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-23  |  26.8 KB  |  996 lines

  1. /* 
  2.  * recovinfo.c --
  3.  *
  4.  *    Put together and print out statistics for recovery purposes such
  5.  *    as the number of file handles in the system file handle table, etc.
  6.  *
  7.  * Copyright 1989 Regents of the University of California
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  */
  16.  
  17. #ifndef lint
  18. static char rcsid[] = "$Header: /sprite/src/cmds/recovinfo/RCS/recovinfo.c,v 1.6 90/09/19 09:22:13 mgbaker Exp Locker: mgbaker $ SPRITE (Berkeley)";
  19. #endif /* not lint */
  20.  
  21. #include    "sprite.h"
  22. #include    "status.h"
  23. #include    "stdio.h"
  24. #include    "list.h"
  25. #include    "hash.h"
  26. #include    "option.h"
  27. #include    "sysStats.h"
  28. #include    "fs.h"
  29. #include    "host.h"
  30.  
  31. /*
  32.  * The stupid decstation compiler can't handle field names in structures that
  33.  * are the same as macro names.
  34.  */
  35. #ifdef ds3100
  36. #undef major
  37. #undef minor
  38. #endif /* ds3100 */
  39.  
  40. /*
  41.  * From kernel/fsio.h
  42.  */
  43. #define    FSIO_NUM_STREAM_TYPES    20
  44.  
  45. /*
  46.  * The format of the information returned from the sys stats system call.
  47.  */
  48. typedef    struct    goo {
  49.     Fs_FileID           fileID;            /* Unique file ID. */
  50.     Boolean        streamHandle;        /* Is this a stream handle? */
  51.     int                 mode;            /* Mode on stream. */
  52.     int                 refCount;        /* Ref count on IO handle. */
  53.     int                 streamRefCount;        /* Ref count on stream. */
  54.     int                 numBlocks;        /* Number of blocks in cache. */
  55.     int                 numDirtyBlocks;        /* Number of diry blocks. */
  56.     char             name[50];        /* Name of object. */
  57. } Sys_FsRecovNamedStats;
  58.  
  59. /*
  60.  * The io types from kernel/fsio.h.
  61.  */
  62. #define FSIO_STREAM                     0
  63. #define FSIO_LCL_FILE_STREAM            1
  64. #define FSIO_RMT_FILE_STREAM            2
  65. #define FSIO_LCL_DEVICE_STREAM          3
  66. #define FSIO_RMT_DEVICE_STREAM          4
  67. #define FSIO_LCL_PIPE_STREAM            5
  68. #define FSIO_RMT_PIPE_STREAM            6
  69. #define FSIO_CONTROL_STREAM             7
  70. #define FSIO_SERVER_STREAM              8
  71. #define FSIO_LCL_PSEUDO_STREAM          9
  72. #define FSIO_RMT_PSEUDO_STREAM          10
  73. #define FSIO_PFS_CONTROL_STREAM         11
  74. #define FSIO_PFS_NAMING_STREAM          12
  75. #define FSIO_LCL_PFS_STREAM             13
  76. #define FSIO_RMT_PFS_STREAM             14
  77. #define FSIO_RMT_CONTROL_STREAM         15
  78. #define FSIO_PASSING_STREAM             16
  79. #define FSIO_RAW_IP_STREAM              17
  80. #define FSIO_UDP_STREAM                 18
  81. #define FSIO_TCP_STREAM                 19
  82.  
  83. /*
  84.  * Hash table of result values, using the unique file ID (Fs_FileID) as
  85.  * a key.  This is okay as long as the ID is a multiple of sizeof (int)!
  86.  */
  87. typedef    struct    oodle    {
  88.     List_Links            streamList;
  89.     Sys_FsRecovNamedStats    *statPtr;
  90. } StatHash;    
  91.  
  92. /*
  93.  * List of streams per handle.
  94.  */
  95. typedef    struct    doodle    {
  96.     List_Links            streamList;
  97.     Sys_FsRecovNamedStats    *statPtr;
  98. } StatList;
  99.  
  100. /*
  101.  * Hash table definitions.
  102.  */
  103. Hash_Table    fileHashTableStruct;
  104. Hash_Table    *fileHashTable = &fileHashTableStruct;
  105. #define        FS_HANDLE_TABLE_SIZE_START    600
  106. int        statKeyType[4];
  107.  
  108. /*
  109.  * The array and number of elements returned from the recov info sys call.
  110.  */
  111. int            numStats = FS_HANDLE_TABLE_SIZE_START;
  112. Sys_FsRecovNamedStats    *stats = (Sys_FsRecovNamedStats *) NULL;
  113.  
  114. /*
  115.  * Summary statistics.
  116.  */
  117. typedef struct    pfeffernusse {
  118.     int                numFileIOHandles;
  119.     int                numFilesNoStream;
  120.     int                numFilesNoStreamAndNotDirty;
  121.     int                numFilesNoStreamAndNotCached;
  122.     int                numWithDirtyBlocks;
  123.     int                totalNumHandlesRecovered;
  124. } Summary;
  125.  
  126. /*
  127.  * Declarations for server list of summary information.
  128.  */
  129. typedef    struct    wiggle {
  130.     List_Links        serverList;
  131.     int            id;
  132.     char        name[50];
  133.     Summary        summary;
  134. } ServerList;
  135.  
  136. /*
  137.  * Option declarations.
  138.  */
  139. Boolean        verbose = FALSE;
  140. Boolean        printFileID = FALSE;
  141. Boolean        printStreamInfo = FALSE;
  142. Boolean        printStreamNames = FALSE;
  143. Boolean        printNames = FALSE;
  144. Boolean        filesOnly = FALSE;
  145. Boolean        allTypes = FALSE;
  146. Boolean        debug = FALSE;
  147. char        *server = (char *) NULL;
  148.  
  149. Option        optionArray[] = {
  150.     {OPT_TRUE, "v", (char *) &verbose, "verbose mode"},
  151.     {OPT_TRUE, "verbose", (char *) &verbose, "verbose mode"},
  152.     {OPT_TRUE, "fileID", (char *) &printFileID, "fileID info"},
  153.     {OPT_TRUE, "fileid", (char *) &printFileID, "fileID info"},
  154.     {OPT_TRUE, "streamInfo", (char *) &printStreamInfo, "stream info"},
  155.     {OPT_TRUE, "streaminfo", (char *) &printStreamInfo, "stream info"},
  156.     {OPT_TRUE, "streamNames", (char *) &printStreamNames, "stream names"},
  157.     {OPT_TRUE, "streamnames", (char *) &printStreamNames, "stream names"},
  158.     {OPT_TRUE, "filesOnly", (char *) &filesOnly, "only local and remote files"},
  159.     {OPT_TRUE, "filesonly", (char *) &filesOnly, "only local and remote les"},
  160.     {OPT_TRUE, "files", (char *) &filesOnly, "only local and remote files"},
  161.     {OPT_TRUE, "all", (char *) &allTypes, "include non-recovered handle types"},
  162.     {OPT_TRUE, "names", (char *) &printNames, "names, cache and IOhandle info"},
  163.     {OPT_TRUE, "debug", (char *) &debug, "Go into the debugger on errors"},
  164.     {OPT_STRING, "server", (char *) &server, "recovery info for objects on this server"}
  165. };
  166. int        numOptions = sizeof (optionArray) / sizeof (Option);
  167.  
  168. extern    char    *GetModeString();
  169. extern    char    *GetFileTypeString();
  170. extern    void    Init();
  171. extern    void    Install();
  172. extern    void    PrintObject();
  173. extern    void    PrintHeader();
  174. extern    char    *mktemp();
  175.  
  176.  
  177. main(argc, argv)
  178.     int        argc;
  179.     char    *argv[];
  180. {
  181.     ReturnStatus        status;
  182.     char            *fileType;
  183.     char            *mode;
  184.     int                i;
  185.     int                bufSize;
  186.     Hash_Search            search;
  187.     Hash_Entry            *entryPtr;
  188.     List_Links            *itemPtr;
  189.     StatList            *streamItemPtr;
  190.     StatHash            *valuePtr;
  191.     FILE            *outputFile;
  192.     int                streamRefCount;
  193.     int                modeInt;
  194.     int                length;
  195.     int                maxLength = 0;
  196.     Boolean            printExtraStuff = FALSE;
  197.     int                myID;
  198.     int                serverID;
  199.     Host_Entry            *serverInfoPtr;
  200.     List_Links            serverList;
  201.     ServerList            *serverItemPtr;
  202.     Summary            total;
  203.     char            tmpFile[20];
  204.     char            systemString[30];
  205. #define    IncSummary(fieldName, serverItemPtr)        \
  206.     total.fieldName++;                    \
  207.     if (serverItemPtr != (ServerList *) NULL) {        \
  208.     serverItemPtr->summary.fieldName++;        \
  209.     }
  210.  
  211.  
  212.     /*
  213.      * Parse arguments.
  214.      */
  215.     Opt_Parse(argc, argv, optionArray, numOptions, 0);
  216.  
  217.     /*
  218.      * Grab stat info from kernel.
  219.      */
  220.     bufSize = numStats * sizeof (Sys_FsRecovNamedStats);
  221.     stats = (Sys_FsRecovNamedStats *) malloc(bufSize);
  222.     status = Sys_Stats(SYS_FS_RECOV_INFO, &bufSize, stats);
  223.  
  224.     /*
  225.      * Did we need more space?
  226.      */
  227.     while (status == SUCCESS && (bufSize >
  228.         numStats * sizeof (Sys_FsRecovNamedStats))) {
  229.     numStats = bufSize / sizeof (Sys_FsRecovNamedStats);
  230.  
  231.     if (stats != (Sys_FsRecovNamedStats *) NULL) {
  232.         free(stats);
  233.     }
  234.     stats = (Sys_FsRecovNamedStats    *) malloc(bufSize);
  235.     status = Sys_Stats(SYS_FS_RECOV_INFO, &bufSize, stats);
  236.     }
  237.  
  238.     if (status != SUCCESS) {
  239.     if (stats != (Sys_FsRecovNamedStats *) NULL) {
  240.         free(stats);
  241.     }
  242.     printf("Stat call failed, status = 0x%x\n", status);
  243.     exit(1);
  244.     }
  245.     
  246.  
  247.     /*
  248.      * Clear total summary statistics.
  249.      */
  250.     bzero(&total, sizeof (total));
  251.  
  252.     /* Init hash table of stats */
  253.     Init();
  254.  
  255.     /* Install stuff in hash table */
  256.     for (i = 0; i < numStats; i++) {
  257.     Install(&stats[i]);
  258.     }
  259.  
  260.     /* open temp file */
  261.     strcpy(tmpFile, "/tmp/tempXXXXXX");
  262.     if (mktemp(tmpFile) != tmpFile) {
  263.     panic("Unable to open output file.\n");
  264.     }
  265.     outputFile = fopen(tmpFile, "w+");
  266.  
  267.     if (outputFile == NULL) {
  268.     panic("Couldn't open output file.\n");
  269.     }
  270.  
  271.     /*
  272.      * The stream ref count is the ref count on stream header, not io handle.
  273.      * An open gives you a new stream (and hence refcount on the io handle).
  274.      * A fork or dup gives you a new ref count on the stream.
  275.      */
  276.  
  277.     /*
  278.      * Do we need to print anything other than a summary?
  279.      */
  280.     if (verbose || printFileID || printStreamInfo || printNames) {
  281.     printExtraStuff = TRUE;
  282.     } else {
  283.     printExtraStuff = FALSE;
  284.     }
  285.  
  286.     status = Proc_GetHostIDs((int *) NULL, &myID);
  287.     if (status != SUCCESS) {
  288.     panic("Couldn't get my host id.\n");
  289.     exit(1);
  290.     }
  291.  
  292.     if (printExtraStuff) {
  293.     /* calculate longest file name for spacing. */
  294.     for (entryPtr = Hash_EnumFirst(fileHashTable, &search);
  295.         entryPtr != NULL; entryPtr = Hash_EnumNext(&search)) {
  296.         valuePtr = (StatHash *) Hash_GetValue(entryPtr);
  297.         if (valuePtr->statPtr == (Sys_FsRecovNamedStats *) NULL) {
  298.         printf("Nil statPtr for stream.\n");
  299.         fflush(stdout);
  300.         continue;
  301.         }
  302.         length = strlen(valuePtr->statPtr->name);
  303.         if (length > maxLength) {
  304.         maxLength = length;
  305.         }
  306.     }
  307.     }
  308.  
  309.     /* print header to file */
  310.     if (printExtraStuff) {
  311.     PrintHeader(&maxLength);
  312.     }
  313.  
  314.     /* Gather info with respect to only one server? */
  315.     if (server != (char *) NULL) {
  316.     serverInfoPtr = Host_ByName(server);
  317.     Host_End();
  318.     serverID = serverInfoPtr->id;
  319.     } else {
  320.     List_Init(&serverList);
  321.     }
  322.  
  323.     /*
  324.      * Go through hash table of handles, gathering information.
  325.      */
  326.     for (entryPtr = Hash_EnumFirst(fileHashTable, &search);
  327.         entryPtr != NULL; entryPtr = Hash_EnumNext(&search)) {
  328.     valuePtr = (StatHash *) Hash_GetValue(entryPtr);
  329.     if (valuePtr->statPtr == (Sys_FsRecovNamedStats *) NULL) {
  330.         printf("Nil statPtr for stream.\n");
  331.         fflush(stdout);
  332.         continue;
  333.     }
  334.     if (valuePtr->statPtr->fileID.type == FSIO_STREAM && debug) {
  335.         panic("Stream type found at first level in table.\n");
  336.     } else if (valuePtr->statPtr->fileID.type == FSIO_STREAM) {
  337.         printf("Stream type found at first level in table.\n");
  338.     }
  339.  
  340.     /*
  341.      * Only remote handles would be recovered.  Is this remote?
  342.      */
  343.     if (!allTypes && valuePtr->statPtr->fileID.serverID == myID) {
  344.         continue;
  345.     }
  346.  
  347.     serverItemPtr = (ServerList *) NULL;
  348.     /*
  349.      * Are we gathering info for only one server?  Is this the one?
  350.      */
  351.     if (server != NULL && serverID != valuePtr->statPtr->fileID.serverID) {
  352.         continue;
  353.     /*
  354.      * Are we gathering info for all servers?  Then find or add this one
  355.      * in the list.
  356.      */
  357.     } else if (server == (char *) NULL) {
  358.         List_Links    *sPtr;
  359.         Boolean    foundServer;
  360.  
  361.         foundServer = FALSE;
  362.         LIST_FORALL(&serverList, sPtr) {
  363.         serverItemPtr = (ServerList *) sPtr;
  364.         if (serverItemPtr->id == valuePtr->statPtr->fileID.serverID) {
  365.             foundServer = TRUE;
  366.             break;
  367.         }
  368.         }
  369.         if (!foundServer) {
  370.         /* Add new server to list. */
  371.         serverItemPtr = (ServerList *) malloc(sizeof (ServerList));
  372.         List_InitElement((List_Links *) serverItemPtr);
  373.         List_Insert((List_Links *) serverItemPtr,
  374.             LIST_ATREAR(&serverList));
  375.         bzero(&(serverItemPtr->summary),
  376.             sizeof (serverItemPtr->summary));
  377.         serverItemPtr->id = valuePtr->statPtr->fileID.serverID;
  378.  
  379.         serverInfoPtr = Host_ByID(serverItemPtr->id);
  380.         Host_End();
  381.         if (serverInfoPtr == (Host_Entry *) NULL) {
  382.             panic("Couldn't get info for a server.\n");
  383.         }
  384.         /*
  385.          * Try to get names without .Berkeley.EDU on the ends.
  386.          */
  387.         if (serverInfoPtr->aliases != NULL &&
  388.             serverInfoPtr->aliases[0] != NULL) {
  389.             strncpy(serverItemPtr->name, serverInfoPtr->aliases[0],
  390.                 sizeof (serverItemPtr->name) - 1);
  391.         } else {
  392.             strncpy(serverItemPtr->name, serverInfoPtr->name,
  393.                 sizeof (serverItemPtr->name) - 1);
  394.             serverItemPtr->name[sizeof(serverItemPtr->name) - 1] = '\0';
  395.         }
  396.         }
  397.     }
  398.     IncSummary(totalNumHandlesRecovered, serverItemPtr);
  399.     fileType = GetFileTypeString(valuePtr->statPtr->fileID.type);
  400.     /*
  401.      * Do statistics specific to files.
  402.      */
  403.     if (valuePtr->statPtr->fileID.type == FSIO_LCL_FILE_STREAM ||
  404.         valuePtr->statPtr->fileID.type == FSIO_RMT_FILE_STREAM) {
  405.         IncSummary(numFileIOHandles, serverItemPtr);
  406.         if (valuePtr->statPtr->refCount == 0) {
  407.         IncSummary(numFilesNoStream, serverItemPtr);
  408.         if (valuePtr->statPtr->numBlocks == 0) {
  409.             IncSummary(numFilesNoStreamAndNotCached, serverItemPtr);
  410.         }
  411.         if (valuePtr->statPtr->numDirtyBlocks == 0) {
  412.             IncSummary(numFilesNoStreamAndNotDirty, serverItemPtr);
  413.         }
  414.         LIST_FORALL(&(valuePtr->streamList), itemPtr) {
  415.             /* I shouldn't find anything here! */
  416.             if (debug) {
  417.             panic(
  418.             "A stream found for an object with no refCount.\n");
  419.             } else {
  420.             printf(
  421.             "A stream found for an object with no refCount.\n");
  422.             }
  423.         }
  424.         }
  425.         if (valuePtr->statPtr->numDirtyBlocks > 0) {
  426.         IncSummary(numWithDirtyBlocks, serverItemPtr);
  427.         }
  428.     }
  429.     /*
  430.      * Go through loop and acquire top mode value and streamRefCount
  431.      * (or is streamRefCount interesting to anybody?).
  432.      */
  433.     modeInt = valuePtr->statPtr->mode;
  434.     streamRefCount = valuePtr->statPtr->streamRefCount;
  435.     LIST_FORALL(&(valuePtr->streamList), itemPtr) {
  436.         streamItemPtr = (StatList *) itemPtr;
  437.         modeInt |= streamItemPtr->statPtr->mode++;
  438.         streamRefCount += streamItemPtr->statPtr->streamRefCount;
  439.         if (streamItemPtr->statPtr->fileID.serverID != myID) {
  440.         IncSummary(totalNumHandlesRecovered, serverItemPtr);
  441.         }
  442.     }
  443.     mode = GetModeString(modeInt);
  444.  
  445.     if (printExtraStuff) {
  446.         PrintObject(outputFile, valuePtr, maxLength, fileType, mode);
  447.     }
  448.     }
  449.     fclose(outputFile);
  450.     sprintf(systemString, "sort %s\n", tmpFile);
  451.     system(systemString);
  452.  
  453.     printf("\n");
  454.     fflush(stdout);
  455.     system("echo SUMMARY `hostname` `date`");
  456.     printf("\n");
  457.     fflush(stdout);
  458.     if (server != (char *) NULL) {
  459.     printf("Server:\t\t\t\t%s\n", server);
  460.     printf("File I/O handles:\t\t%d\n",
  461.         total.numFileIOHandles);
  462.     printf("Files with no stream:\t\t%d\n",
  463.         total.numFilesNoStream);
  464.     printf("No stream nor cache blocks:\t%d\n",
  465.         total.numFilesNoStreamAndNotCached);
  466.     printf("No stream nor dirty blocks:\t%d\n",
  467.         total.numFilesNoStreamAndNotDirty);
  468.     printf("Files with dirty blocks:\t%d\n",
  469.         total.numWithDirtyBlocks);
  470.     printf("Total handles to recover:\t%d\n",
  471.         total.totalNumHandlesRecovered);
  472.     } else {
  473.     List_Links    *sPtr;
  474.  
  475.     printf("Server:\t\t\t\t");
  476.     LIST_FORALL(&serverList, sPtr) {
  477.         serverItemPtr = (ServerList *) sPtr;
  478.         printf("%s\t", serverItemPtr->name);
  479.     }
  480.     printf("combined\n");
  481.     printf("File I/O handles:\t\t");
  482.     LIST_FORALL(&serverList, sPtr) {
  483.         serverItemPtr = (ServerList *) sPtr;
  484.         printf("%d\t", serverItemPtr->summary.numFileIOHandles);
  485.         if (strlen(serverItemPtr->name) >= 8) {
  486.         printf("\t");
  487.         }
  488.     }
  489.     printf("%d\n", total.numFileIOHandles);
  490.     printf("Files with no stream:\t\t");
  491.     LIST_FORALL(&serverList, sPtr) {
  492.         serverItemPtr = (ServerList *) sPtr;
  493.         printf("%d\t", serverItemPtr->summary.numFilesNoStream);
  494.         if (strlen(serverItemPtr->name) >= 8) {
  495.         printf("\t");
  496.         }
  497.     }
  498.     printf("%d\n", total.numFilesNoStream);
  499.     printf("No stream nor cache blocks:\t");
  500.     LIST_FORALL(&serverList, sPtr) {
  501.         serverItemPtr = (ServerList *) sPtr;
  502.         printf("%d\t", serverItemPtr->summary.numFilesNoStreamAndNotCached);
  503.         if (strlen(serverItemPtr->name) >= 8) {
  504.         printf("\t");
  505.         }
  506.     }
  507.     printf("%d\n", total.numFilesNoStreamAndNotCached);
  508.     printf("No stream nor dirty blocks:\t");
  509.     LIST_FORALL(&serverList, sPtr) {
  510.         serverItemPtr = (ServerList *) sPtr;
  511.         printf("%d\t", serverItemPtr->summary.numFilesNoStreamAndNotDirty);
  512.         if (strlen(serverItemPtr->name) >= 8) {
  513.         printf("\t");
  514.         }
  515.     }
  516.     printf("%d\n", total.numFilesNoStreamAndNotDirty);
  517.     printf("Files with dirty blocks:\t");
  518.     LIST_FORALL(&serverList, sPtr) {
  519.         serverItemPtr = (ServerList *) sPtr;
  520.         printf("%d\t", serverItemPtr->summary.numWithDirtyBlocks);
  521.         if (strlen(serverItemPtr->name) >= 8) {
  522.         printf("\t");
  523.         }
  524.     }
  525.     printf("%d\n", total.numWithDirtyBlocks);
  526.     printf("Total handles to recover:\t");
  527.     LIST_FORALL(&serverList, sPtr) {
  528.         serverItemPtr = (ServerList *) sPtr;
  529.         printf("%d\t", serverItemPtr->summary.totalNumHandlesRecovered);
  530.         if (strlen(serverItemPtr->name) >= 8) {
  531.         printf("\t");
  532.         }
  533.     }
  534.     printf("%d\n", total.totalNumHandlesRecovered);
  535.     }
  536.  
  537.     fflush(stdout);
  538.  
  539.     (void) unlink(tmpFile);
  540.     exit(0);
  541. }
  542.  
  543.  
  544.  
  545. /*
  546.  *----------------------------------------------------------------------
  547.  *
  548.  * GetFileTypeString --
  549.  *
  550.  *    Get a string representing file type.
  551.  *
  552.  * Results:
  553.  *    The string.
  554.  *
  555.  * Side effects:
  556.  *    None.
  557.  *
  558.  *----------------------------------------------------------------------
  559.  */
  560. char *
  561. GetFileTypeString(type)
  562.     int    type;
  563. {
  564.     char    *fileType;
  565.  
  566.     switch (type) {
  567.     case FSIO_STREAM:
  568.     if (debug) {
  569.         panic("Stream type found at first level in table.\n");
  570.     } else {
  571.         printf("Stream type found at first level in table.\n");
  572.     }
  573.     case FSIO_LCL_FILE_STREAM:
  574.     fileType = "File";
  575.     break;
  576.     case FSIO_RMT_FILE_STREAM:
  577.     fileType = "RmtFile";
  578.     break;
  579.     case FSIO_LCL_DEVICE_STREAM:
  580.     fileType = "Device";
  581.     break;
  582.     case FSIO_RMT_DEVICE_STREAM:
  583.     fileType = "RmtDevice";
  584.     break;
  585.     case FSIO_LCL_PIPE_STREAM:
  586.     fileType = "Pipe";
  587.     break;
  588.     case FSIO_RMT_PIPE_STREAM:
  589.     fileType = "RmtPipe";
  590.     break;
  591. #ifdef notdef
  592.     case FS_LCL_NAMED_PIPE_STREAM:
  593.     fileType = "NamedPipe";
  594.     break;
  595.     case FS_RMT_NAMED_PIPE_STREAM:
  596.     fileType = "RmtNamedPipe";
  597.     break;
  598. #endif
  599.     case FSIO_CONTROL_STREAM:
  600.     fileType = "PdevControlStream";
  601.     break;
  602.     case FSIO_SERVER_STREAM:
  603.     fileType = "SrvStream";
  604.     break;
  605.     case FSIO_LCL_PSEUDO_STREAM:
  606.     fileType = "LclPdev";
  607.     break;
  608.     case FSIO_RMT_PSEUDO_STREAM:
  609.     fileType = "RmtPdev";
  610.     break;
  611.     case FSIO_PFS_CONTROL_STREAM:
  612.     fileType = "PfsControlStream";
  613.     break;
  614.     case FSIO_PFS_NAMING_STREAM:
  615.     fileType = "PfsNamingStream";
  616.     break;
  617.     case FSIO_LCL_PFS_STREAM:
  618.     fileType = "LclPfs";
  619.     break;
  620.     case FSIO_RMT_PFS_STREAM:
  621.     fileType = "RmtPfs";
  622.     break;
  623. #ifdef INET
  624.     case FSIO_RAW_IP_STREAM:
  625.     fileType = "RawIp Socket";
  626.     break;
  627.     case FSIO_UDP_STREAM:
  628.     fileType = "UDP Socket";
  629.     break;
  630.     case FSIO_TCP_STREAM:
  631.     fileType = "TCP Socket";
  632.     break;
  633. #endif
  634. #ifdef notdef
  635.     case FS_RMT_UNIX_STREAM:
  636.     fileType = "UnixFile";
  637.     break;
  638.     case FS_RMT_NFS_STREAM:
  639.     fileType = "NFSFile";
  640.     break;
  641. #endif
  642.     default:
  643.     /*
  644.      * Brent puts <>'s around this in all his error printing.  But without
  645.      * them, it's the same length as the longest file type, which is
  646.      * convenient for printing.  And we should never see this anyway.
  647.      */
  648.     fileType = "unknown file type";
  649.     break;
  650.     }
  651.  
  652.     return fileType;
  653. }
  654.  
  655. int
  656. MaxFileTypeNameLength()
  657. {
  658.     return strlen("PdevControlStream");
  659. }
  660.  
  661.  
  662.  
  663. /*
  664.  *----------------------------------------------------------------------
  665.  *
  666.  * GetModeString --
  667.  *
  668.  *    Get a string representing mode.
  669.  *
  670.  * Results:
  671.  *    The string.
  672.  *
  673.  * Side effects:
  674.  *    None.
  675.  *
  676.  *----------------------------------------------------------------------
  677.  */
  678. char *
  679. GetModeString(modeInt)
  680.     int    modeInt;
  681. {
  682.     char    *mode;
  683.  
  684.     if ((modeInt & FS_READ) && (modeInt & FS_WRITE) && (modeInt & FS_EXECUTE) &&
  685.         (modeInt & FS_APPEND)) {
  686.     mode = "RWXA";
  687.     } else if ((modeInt & FS_READ) && (modeInt & FS_WRITE) &&
  688.         (modeInt & FS_EXECUTE)) {
  689.     mode = "RWX";
  690.     } else if ((modeInt & FS_READ) && (modeInt & FS_WRITE) &&
  691.         (modeInt & FS_APPEND)) {
  692.     mode = "RWA";
  693.     } else if ((modeInt & FS_READ) && (modeInt & FS_WRITE)) {
  694.     mode = "RW";
  695.     } else if ((modeInt & FS_READ) && (modeInt & FS_EXECUTE)) {
  696.     mode = "RX";
  697.     } else if ((modeInt & FS_READ) && (modeInt & FS_APPEND)) {
  698.     mode = "RA";
  699.     } else if (modeInt & FS_READ) {
  700.     mode = "R";
  701.     } else if ((modeInt & FS_WRITE) && (modeInt & FS_EXECUTE) &&
  702.         (modeInt & FS_APPEND)) {
  703.     mode = "WXA";
  704.     } else if ((modeInt & FS_WRITE) && (modeInt & FS_EXECUTE)) {
  705.     mode = "WX";
  706.     } else if ((modeInt & FS_WRITE) && (modeInt & FS_APPEND)) {
  707.     mode = "WA";
  708.     } else if (modeInt & FS_WRITE) {
  709.     mode = "W";
  710.     } else if ((modeInt & FS_EXECUTE) && (modeInt & FS_APPEND)) {
  711.     mode = "XA";
  712.     } else if (modeInt & FS_EXECUTE) {
  713.     mode = "X";
  714.     } else if (modeInt & FS_APPEND) {
  715.     mode = "A";
  716.     } else {
  717.     mode = "none";
  718.     }
  719.  
  720.     return mode;
  721. }
  722.  
  723.  
  724. /*
  725.  *----------------------------------------------------------------------
  726.  *
  727.  * Init --
  728.  *
  729.  *    Initialize the hash table of statistics.   We hash on the fileID of
  730.  *    of the fileHandle info.
  731.  *
  732.  * Results:
  733.  *    None.
  734.  *
  735.  * Side effects:
  736.  *    Hash table created.
  737.  *
  738.  *----------------------------------------------------------------------
  739.  */
  740. void
  741. Init()
  742. {
  743.     Hash_InitTable(fileHashTable, numStats,
  744.         sizeof (statKeyType) / sizeof (int)); 
  745.     return;
  746. }
  747.  
  748.  
  749.  
  750. /*
  751.  *----------------------------------------------------------------------
  752.  *
  753.  * Install --
  754.  *
  755.  *    Install and entry into the hash table of statistics.
  756.  *
  757.  * Results:
  758.  *    None.
  759.  *
  760.  * Side effects:
  761.  *    New entry installed if it wasn't previously there.
  762.  *
  763.  *----------------------------------------------------------------------
  764.  */
  765. void
  766. Install(statPtr)
  767.     Sys_FsRecovNamedStats    *statPtr;
  768. {
  769.     Hash_Entry        *hashEntryPtr;
  770.     Boolean        newP;
  771.     StatHash        *valuePtr;
  772.     StatList        *itemPtr;
  773.  
  774.     /*
  775.      * For a key, use everything except the type.
  776.      */
  777.     if (statPtr->name[0] == '\0' && statPtr->fileID.serverID == 0 &&
  778.         statPtr->fileID.major == 0 && statPtr->fileID.minor == 0) {
  779.     return;
  780.     }
  781.     statKeyType[0] = statPtr->fileID.serverID;
  782.     statKeyType[1] = statPtr->fileID.major;
  783.     statKeyType[2] = statPtr->fileID.minor;
  784.     statKeyType[3] = statPtr->fileID.type;
  785.  
  786.     hashEntryPtr = Hash_CreateEntry(fileHashTable, (Address) statKeyType,
  787.         &newP);
  788.     if (newP) {
  789.     valuePtr = (StatHash *) malloc(sizeof (StatHash));
  790.     Hash_SetValue(hashEntryPtr, (Address) valuePtr);
  791.     valuePtr->statPtr = (Sys_FsRecovNamedStats *) NULL;
  792.     List_Init(&(valuePtr->streamList));
  793.     } else {
  794.     valuePtr = (StatHash *) Hash_GetValue(hashEntryPtr);
  795.     }
  796.  
  797.     if (! statPtr->streamHandle) {
  798.     /* Make into base object */
  799.     if (valuePtr->statPtr == (Sys_FsRecovNamedStats *) NULL) {
  800.         valuePtr->statPtr = statPtr;
  801.     } else if (debug) {
  802.         panic("More than one IO handle object for this ID!\n");
  803.     } else {
  804.         printf("More than one IO handle object for this ID!\n");
  805.     }
  806.     } else {
  807.     /* Add stream to stream list */
  808.     itemPtr = (StatList *) malloc(sizeof (StatList));
  809.     itemPtr->statPtr = statPtr;
  810.     List_InitElement((List_Links *) itemPtr);
  811.     List_Insert(itemPtr, LIST_ATREAR(&(valuePtr->streamList)));
  812.     }
  813.  
  814.     return;
  815. }
  816.  
  817.  
  818. /*
  819.  *----------------------------------------------------------------------
  820.  *
  821.  * PrintHeader --
  822.  *
  823.  *    Print out a header for object information.
  824.  *
  825.  * Results:
  826.  *    None.
  827.  *
  828.  * Side effects:
  829.  *    The length of maxLength may be increased.
  830.  *
  831.  *----------------------------------------------------------------------
  832.  */
  833. void
  834. PrintHeader(maxLengthPtr)
  835.     int        *maxLengthPtr;
  836. {
  837.     int        i;
  838.  
  839.     if (*maxLengthPtr < strlen("Name")) {
  840.     *maxLengthPtr = strlen("Name");
  841.     }
  842.     printf("Name");
  843.     for (i = 0; i < *maxLengthPtr - strlen("Name") + 2; i++) {
  844.     printf(" ");
  845.     }
  846.     printf("Type");
  847.     for (i = 0; i < MaxFileTypeNameLength() - strlen("Type") + 2; i++) {
  848.     printf(" ");
  849.     }
  850.     if (verbose || printFileID) {
  851.     printf("FileID");
  852.     for (i = 0; i < strlen("(xx,xxxxxx,xxxxxxxx)") - strlen("FileID") + 2;
  853.         i++) {
  854.         printf(" ");
  855.     }
  856.     }
  857.     if (verbose || printStreamInfo) {
  858.     printf("Mode  Dup/ForkCount  ");
  859.     }
  860.     printf("RefCount  NumBlocks  NumDirtyBlocks\n");
  861.     fflush(stdout);
  862.  
  863.     return;
  864. }
  865.  
  866.  
  867. /*
  868.  *----------------------------------------------------------------------
  869.  *
  870.  * PrintObject --
  871.  *
  872.  *    Print information for one file system object.
  873.  *
  874.  * Results:
  875.  *    None.
  876.  *
  877.  * Side effects:
  878.  *    None.
  879.  *
  880.  *----------------------------------------------------------------------
  881.  */
  882. void
  883. PrintObject(outputFile, valuePtr, maxLength, fileType, mode)
  884.     FILE    *outputFile;
  885.     StatHash    *valuePtr;
  886.     int        maxLength;
  887.     char    *fileType;
  888.     char    *mode;
  889.  
  890. {
  891.     int        i;
  892.     List_Links    *itemPtr;
  893.     StatList    *streamItemPtr;
  894.  
  895.     if (filesOnly && (valuePtr->statPtr->fileID.type != FSIO_LCL_FILE_STREAM &&
  896.         valuePtr->statPtr->fileID.type != FSIO_RMT_FILE_STREAM)) {
  897.     return;
  898.     }
  899.     fprintf(outputFile, valuePtr->statPtr->name);
  900.     for (i = 0; i < maxLength - strlen(valuePtr->statPtr->name) + 2; i++) {
  901.     fprintf(outputFile, " ");
  902.     }
  903.     fprintf(outputFile, fileType);
  904.     for (i = 0; i < MaxFileTypeNameLength() - strlen(fileType) + 2; i++) {
  905.     fprintf(outputFile, " ");
  906.     }
  907.     if (verbose || printFileID) {
  908.     fprintf(outputFile, "(%-2d,%6x,%8x)",
  909.         valuePtr->statPtr->fileID.serverID,
  910.         valuePtr->statPtr->fileID.major,
  911.         valuePtr->statPtr->fileID.minor);
  912.     fprintf(outputFile, "  ");
  913.     }
  914.     if (verbose || printStreamInfo) {
  915.     fprintf(outputFile, mode);
  916.     for (i = 0; i < strlen("mode") - strlen(mode) + 2; i++) {
  917.         fprintf(outputFile, " ");
  918.     }
  919.     fprintf(outputFile, "%d", valuePtr->statPtr->streamRefCount);
  920.     if (valuePtr->statPtr->streamRefCount < 10) {
  921.         for (i = 0; i < strlen("Dup/ForkCount") + 2 - 1; i++) {
  922.         fprintf(outputFile, " ");
  923.         }
  924.     } else if (valuePtr->statPtr->streamRefCount < 100) {
  925.         for (i = 0; i < strlen("Dup/ForkCount") + 2 - 2; i++) {
  926.         fprintf(outputFile, " ");
  927.         }
  928.     } else if (valuePtr->statPtr->streamRefCount < 1000) {
  929.         for (i = 0; i < strlen("Dup/ForkCount") + 2 - 3; i++) {
  930.         fprintf(outputFile, " ");
  931.         }
  932.     } else if (debug) {
  933.         panic("The stream ref count is too long for my printer routine.\nFix the silly printer routine.\n");
  934.     } else {
  935.         printf("The stream ref count is too long for my printer routine.\nFix the silly printer routine.\n");
  936.     }
  937.     }
  938.  
  939.     fprintf(outputFile, "%d", valuePtr->statPtr->refCount);
  940.     if (valuePtr->statPtr->refCount < 10) {
  941.     for (i = 0; i < strlen("RefCount") + 2 - 1; i++) {
  942.         fprintf(outputFile, " ");
  943.     }
  944.     } else if (valuePtr->statPtr->refCount < 100) {
  945.     for (i = 0; i < strlen("RefCount") + 2 - 2; i++) {
  946.         fprintf(outputFile, " ");
  947.     }
  948.     } else if (valuePtr->statPtr->refCount < 1000) {
  949.     for (i = 0; i < strlen("RefCount") + 2 - 3; i++) {
  950.         fprintf(outputFile, " ");
  951.     }
  952.     } else if (debug) {
  953.     panic("The ref count is too long for my printer routine.\nFix the silly printer routine.\n");
  954.     } else {
  955.     printf("The ref count is too long for my printer routine.\nFix the silly printer routine.\n");
  956.     }
  957.     fprintf(outputFile, "%d", valuePtr->statPtr->numBlocks);
  958.     if (valuePtr->statPtr->numBlocks < 10) {
  959.     for (i = 0; i < strlen("NumBlocks") + 2 - 1; i++) {
  960.         fprintf(outputFile, " ");
  961.     }
  962.     } else if (valuePtr->statPtr->numBlocks < 100) {
  963.     for (i = 0; i < strlen("NumBlocks") + 2 - 2; i++) {
  964.         fprintf(outputFile, " ");
  965.     }
  966.     } else if (valuePtr->statPtr->numBlocks < 1000) {
  967.     for (i = 0; i < strlen("NumBlocks") + 2 - 3; i++) {
  968.         fprintf(outputFile, " ");
  969.     }
  970.     } else if (debug) {
  971.     panic("The count of blocks is too long for my printer routine.\nFix the silly printer routine.\n");
  972.     } else {
  973.     printf("The count of blocks is too long for my printer routine.\nFix the silly printer routine.\n");
  974.     }
  975.     fprintf(outputFile, "%d", valuePtr->statPtr->numDirtyBlocks);
  976.  
  977.     fprintf(outputFile, "\n");
  978.  
  979.     if (printStreamNames) {
  980.     /* Handle list of streams now, take this out after testing. */
  981.     LIST_FORALL(&(valuePtr->streamList), itemPtr) {
  982.         streamItemPtr = (StatList *) itemPtr;
  983.         fprintf(outputFile, "%s", streamItemPtr->statPtr->name);
  984.         for (i = 0; i < maxLength - strlen(valuePtr->statPtr->name) + 2;
  985.             i++) {
  986.         fprintf(outputFile, " ");
  987.         }
  988.         fprintf(outputFile, "Stream: %s\n",
  989.             GetFileTypeString(streamItemPtr->statPtr->fileID.type));
  990.     }
  991.     }
  992.     fflush(outputFile);
  993.  
  994.     return;
  995. }
  996.